package com.cskaoyan.mall.promo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cskaoyan.mall.common.constant.RedisConst;
import com.cskaoyan.mall.common.constant.ResultCodeEnum;
import com.cskaoyan.mall.common.execption.BusinessException;
import com.cskaoyan.mall.common.result.Result;
import com.cskaoyan.mall.common.util.AuthContext;
import com.cskaoyan.mall.common.util.DateUtil;
import com.cskaoyan.mall.common.util.MD5;
import com.cskaoyan.mall.order.dto.OrderDetailDTO;
import com.cskaoyan.mall.order.dto.OrderInfoDTO;
import com.cskaoyan.mall.order.dto.OrderTradeDTO;
import com.cskaoyan.mall.order.query.OrderDetailParam;
import com.cskaoyan.mall.order.query.OrderInfoParam;
import com.cskaoyan.mall.promo.api.dto.SeckillGoodsDTO;
import com.cskaoyan.mall.promo.client.OrderApiClient;
import com.cskaoyan.mall.promo.client.UserApiClient;
import com.cskaoyan.mall.promo.constant.SeckillCodeEnum;
import com.cskaoyan.mall.promo.constant.SeckillGoodsStatus;
import com.cskaoyan.mall.promo.converter.SeckillGoodsConverter;
import com.cskaoyan.mall.promo.mapper.SeckillGoodsMapper;
import com.cskaoyan.mall.promo.model.OrderRecord;
import com.cskaoyan.mall.promo.model.SeckillGoods;
import com.cskaoyan.mall.promo.model.UserRecord;
import com.cskaoyan.mall.promo.service.PromoService;
import com.cskaoyan.mall.promo.util.LocalCacheHelper;
import com.cskaoyan.mall.user.dto.UserAddressDTO;
import com.mysql.cj.protocol.ResultBuilder;
import org.redisson.api.RMap;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Macro_Ray
 * @since 2024/6/25 下午2:33
 */
@RestController
@RequestMapping("/seckill")
public class PromoController {

    @Autowired
    RedissonClient redissonClient;
    @Autowired
    UserApiClient userApiClient;
    @Autowired
    OrderApiClient orderApiClient;
    @Autowired
    SeckillGoodsConverter seckillGoodsConverter;
    @Autowired
    PromoService promoService;
    @Autowired
    SeckillGoodsMapper seckillGoodsMapper;

    /**
     * 返回全部秒杀商品列表
     */
    @GetMapping
    public Result<List<SeckillGoodsDTO>> findAll() {
        return Result.ok(promoService.findAll());
    }

    /**
     * 获取秒杀商品详情
     *
     * @param skuId
     */
    @GetMapping("/{skuId}")
    public Result<SeckillGoodsDTO> getSeckillGoods(@PathVariable("skuId") Long skuId) {
        return Result.ok(promoService.getSeckillGoodsDTO(skuId));
    }

    /**
     * 获取下单码，下单码可以在跳转到支付页面时使用，用于校验订单是否有效
     *
     * @param skuId
     * @param request
     */
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result<String> getSeckillSkuIdStr(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
        // 1 判断秒杀活动是否存在
        SeckillGoodsDTO seckillGoodsDTO = promoService.getSeckillGoodsDTO(skuId);
        // 2 获取当前时间
        Date now = new Date();
        if (DateUtil.dateCompare(seckillGoodsDTO.getStartTime(), now)
                && DateUtil.dateCompare(now, seckillGoodsDTO.getEndTime())) {
            // 在秒杀活动的开展时间之内，生成秒杀下单码
            String userId = AuthContext.getUserId(request);
            String codeStr = MD5.encrypt(userId + skuId);
            // 3 将下单码存入redis，并设置过期时间 todo 优化
            // RMap<String, String> codeMap = redissonClient.getMap(RedisConst.);
            // codeMap.put(codeStr, skuId.toString(), 60 * 5);
            // 4 返回下单码
            return Result.ok(codeStr);
        }
        return Result.fail("").message("获取下单码失败");
    }

    /**
     * 秒杀商品确认订单结算页
     *
     * @param request
     */
    @GetMapping("/auth/trade/{skuId}")
    public Result<OrderTradeDTO> trade(@PathVariable("skuId") Long skuId, String skuIdStr, HttpServletRequest request) {
        // 1 根据下单码判断是否是合法请求
        // 1.1 获取userId
        String userId = AuthContext.getUserId(request);
        // 1.2 生成一个下单码
        String codeStr = MD5.encrypt(userId + skuId);
        if (!codeStr.equals(skuIdStr)){
            // 非法请求
            return Result.build(null,SeckillCodeEnum.SECKILL_ILLEGAL);
        }
        // 2 校验秒杀商品库存是否售罄  状态标志位
        String status = (String) LocalCacheHelper.get(skuId.toString());
        if ("0".equals(status)){
            // 秒杀商品已售罄
            return Result.build(null,SeckillCodeEnum.SECKILL_FINISH);
        }
        // 3 获取秒杀商品详情
        promoService.getTradeData(userId,skuId);
        return Result.ok();
    }

    /**
     * 提交订单
     *
     * @param orderInfo
     * @param request
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfoParam orderInfo, HttpServletRequest request) {
        // 获取秒杀商品信息
        OrderDetailParam orderDetailParam = orderInfo.getOrderDetailList().get(0);
        // 获取userId
        String userId = AuthContext.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));

        // 1 判断下单的商品是否售罄
        Long skuId = orderDetailParam.getSkuId();
        String status = (String) LocalCacheHelper.get(skuId.toString());
        if ("0".equals(status)){
            // 秒杀商品已售罄
            return Result.build(null,SeckillCodeEnum.SECKILL_FINISH);
        }

        // 2 准备下单
        promoService.submitOrder(orderInfo);

        return Result.build(null, SeckillCodeEnum.SECKILL_ORDER_SUCCESS);
    }

    /**
     * 前端轮训，秒杀，检查下单状态
     *
     * @param skuId
     * @param request
     */
    @GetMapping(value = "/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
        return Result.build(null, SeckillCodeEnum.SECKILL_RUN);
    }

    @GetMapping("/clear")
    public Result clearTest() {
        promoService.clearCache();
        return Result.ok();
    }
}
